package io.github.talelin.latticy.util;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @authoer:wulongbo
 * @createDate:2022/6/6
 * @description:
 */
public class MapperUtils {

    /**
     * 得到泛型(继承baseMapper)
     */
    public static <T> Class<T> getClassByClassT(BaseMapper<T> baseMapper) {
        Type genericSuperclass = baseMapper.getClass().getGenericSuperclass();
        // 强转成 参数化类型 实体.
        ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
        // 获取超类的泛型类型数组. 即SuperClass<User>的<>中的内容, 因为泛型可以有多个, 所以用数组表示
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
        Type genericType = actualTypeArguments[0];
        Class<T> clazz = (Class<T>) genericType;
        return clazz;
    }


    /**
     * 根据BaseMapper抽象类得到泛型的实例
     *
     * @param baseMapper 带泛型的实例
     * @return 泛型的实例对象
     */
    public static <T> T getEntityByClassT(BaseMapper<T> baseMapper) {
        Class<T> clazz = getClassByClassT(baseMapper);
        T e = null;
        try {
            if (clazz != null) {
                e = clazz.newInstance();
            }
        } catch (InstantiationException instantiationException) {
            instantiationException.printStackTrace();
        } catch (IllegalAccessException illegalAccessException) {
            illegalAccessException.printStackTrace();
        }
        return e;
    }


    /**
     * 获取泛型的类型(实现baseMapper)
     */
    public static <T> Class<T> getClassByInterfaceT(BaseMapper<T> baseMapper) {
        Type[] genericInterfaces = baseMapper.getClass().getGenericInterfaces();
        if (genericInterfaces.getClass().isAssignableFrom(ParameterizedType[].class)) {
            for (Type genericInterface : genericInterfaces) {
                ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                Type type = actualTypeArguments[0];
                if (type instanceof Class) {
                    return (Class<T>) type;
                }
            }
        }
        return null;
    }

    /**
     * 获取实例对象，（实现baseMapper）
     * 根据接口中的泛型返回对应的实体,例如 XXXMapper implements HcBaseMapper<T>
     */
    public static <T> T getEntityByInterfaceT(BaseMapper<T> baseMapper) {
        Class<T> clazz = getClassByInterfaceT(baseMapper);
        T e = null;
        try {
            if (clazz != null) {
                e = clazz.newInstance();
            }
        } catch (InstantiationException instantiationException) {
            instantiationException.printStackTrace();
        } catch (IllegalAccessException illegalAccessException) {
            illegalAccessException.printStackTrace();
        }
        return e;
    }
}
